using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using HtmlAgilityPack;

namespace WhySoSeries
{
    public class TvCountDownDataExtractor : SeriesDataExtractor
    {
        private List<string> scriptResults;
        private WebsiteFactory factory;

        public TvCountDownDataExtractor(WebsiteFactory factory, string link)
            : base(link)
        {
            this.factory = factory;

        }

        public TvCountDownDataExtractor(WebsiteFactory factory, Series series)
            : base(series)
        {
            this.factory = factory;
        }

        private void InitializeScriptResults()
        {
            this.scriptResults = new List<string>();

            string script = base.document.DocumentNode.SelectSingleNode("/html/body/script[4]").InnerText; //extracts the dates script
            Regex regex = new Regex("'(.*?)'"); //seperates the dates.
            var match = regex.Matches(script);

            for (int i = 0; i < match.Count / 2; i++) // the first half of this script is the dates
                this.scriptResults.Add(match[i].Groups[1].Value); 
        }

        protected override HtmlDocument GetSeriesHtmlDocument(string link, DataExtractionMode mode)
        {
            if(mode == DataExtractionMode.LastEpisodes)
                return WebUtilities.GetHtmlDocument(link);
            if (mode == DataExtractionMode.AllEpisodes)
                return WebUtilities.GetHtmlDocument(link + "?all");
            return null;
        }

        protected override List<HtmlNode> GetEpisodeElements()
        {
            return this.document.DocumentNode.SelectNodes("//*[@id='agenda']/div/div").Skip(1).ToList();
        }

        protected override string GetSeriesName()
        {
            return this.document.DocumentNode.SelectSingleNode("//*[@id='show-title']").InnerText;
        }

        protected override Episode GetEpisodeByHtmlNode(HtmlNode node, int index)
        {
            string episodeName;
            int episodeNumber;
            int seasonNumber;
            DateTime? episodeTime;

            if (this.scriptResults == null)
                InitializeScriptResults();

            //Get episode name
            episodeName = node.SelectSingleNode("//div[@class='five columns']").InnerText;

            //Get season and episode numbers
            string seasonAndEpisodeNumbers = node.SelectSingleNode("//div[@class='two columns']").InnerText;
            Tuple<int, int> numbers = ParseUtilities.GetSeasonAndEpisodeNumbersFromString(seasonAndEpisodeNumbers);
            seasonNumber = numbers.Item1;
            episodeNumber = numbers.Item2;

            //Get episode time
            try
            {
                string dateTime = this.scriptResults[index];
                const string timeFormat = "dd MMMM, yyyy HH:mm:ss";
                episodeTime = DateTime.ParseExact(dateTime, timeFormat, CultureInfo.InvariantCulture);
                episodeTime = episodeTime.Value.AddHours(7); //7 hours alignment
            }
            catch (FormatException)
            {
                episodeTime = null;
            }

            Season season = new Season(this.Series, seasonNumber);
            Episode episode = new Episode(season, episodeName, episodeNumber, episodeTime);
            return episode;
        }
    }
}